#include "ball.h"
#include <QPainter>

Ball::Ball( QGraphicsScene *scene, QObject *object, QGraphicsItem *parent )
    : QObject( object ), QGraphicsItem( parent ), m_scene( scene ), m_topLimit( 0 )
{
    setFlags ( QGraphicsItem::ItemIsMovable );

    m_bottomLimit = scene->height() - m_diameter;
    m_hgt = scene->height() - y();
    m_topLimit = m_scene->height() - m_diameter - m_hgt;
    m_direction = DOWN;

    m_timer = new QTimer( this );
    connect( m_timer, SIGNAL(timeout()), this, SLOT(move()) );
    m_timer->start( m_interval );
}

QRectF Ball::boundingRect() const
{
    return QRectF( 0, 0, m_diameter, m_diameter );
}

void Ball::paint( QPainter *painter,
                  const QStyleOptionGraphicsItem *option,
                  QWidget *widget )
{
    painter->setPen( Qt::black );
    painter->setBrush( Qt::yellow );
    painter->drawEllipse( QRectF( 0, 0, m_diameter, m_diameter ) );
}

void Ball::move()
{
    switch ( m_direction ) {
    case UP:
        if ( y() > m_topLimit ) {
            smoothMove();
            moveBy( 0, -m_step );
        }
        else
            m_direction = DOWN;
        break;
    case DOWN:
        if ( y() < m_bottomLimit ) {
            smoothMove();
            moveBy( 0, m_step );
        }
        else {
            m_direction = UP;
            bounce();
        }
        break;
    }
}

void Ball::smoothMove()
{
    if ( y() <= (m_scene->height() - m_hgt * 0.9) )
        m_timer->setInterval( m_interval + 2 );
    if ( y() > (m_scene->height() - m_hgt * 0.95) )
        m_timer->setInterval( m_interval );
}

void Ball::mousePressEvent( QGraphicsSceneMouseEvent *e )
{
    m_timer->stop();
    QGraphicsItem::mousePressEvent( e );
}

void Ball::mouseReleaseEvent( QGraphicsSceneMouseEvent *e )
{
    m_direction = DOWN;
    m_hgt = m_scene->height() - m_diameter - y();
    m_timer->start( m_interval );
    QGraphicsItem::mouseReleaseEvent( e );
}

#include <math.h>
void Ball::bounce()
{
    m_v = sqrt( 2 * m_g * m_hgt );
    m_hgt = (m_v * m_v) / (2 * m_g);
    m_topLimit = m_scene->height() - m_diameter - m_hgt;
}

int Ball::diameter()
{
    return m_diameter;
}
